package com.billionsfinance.crs.hessian.core;

import com.billionsfinance.crs.hessian.annotation.HessianPath;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.remoting.caucho.HessianServiceExporter;


/**
 * hessian server 端动态注册hessian服务
 *
 * @ ClassName: HessianServerBeanFactory.java
 * @ Author: WeiHui-Z
 * @ Date: 2016/12/23 10:46
 * @ Version: v1.0.0
 */
@Order
public class HessianServerBeanFactory implements ApplicationContextAware {

	private static final Logger LOGGER = LoggerFactory.getLogger(HessianServerBeanFactory.class);

	/**
	 * 访问后缀
	 */
	private String suffix = "";

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		ConfigurableApplicationContext context = (ConfigurableApplicationContext) applicationContext;
		DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getBeanFactory();
		Map<String, Object> beans = context.getBeanFactory().getBeansWithAnnotation(HessianPath.class);
		Set<Map.Entry<String, Object>> entries = beans.entrySet();
		for (Map.Entry<String, Object> entry : entries) {
			String refBean = entry.getKey();
			Object value = entry.getValue();
			Class<?> clazz = value.getClass();
			Class<?> interfaces = clazz.getInterfaces()[0];

			LOGGER.info("Register hessian server bean: {}", clazz);
			registerBeanDefinition(beanFactory, refBean, interfaces);
		}
	}

	/**
	 * 创建bean并且放入springBean工厂，取代xml的繁琐配置
	 *
	 * @param beanFactory               bean工厂
	 * @param hessianServiceImplRefBean serviceImpl--bean 的名称
	 * @param hessianServiceInterface   service的全类名
	 */
	private void registerBeanDefinition(DefaultListableBeanFactory beanFactory, String hessianServiceImplRefBean, Class<?> hessianServiceInterface) {
		// 通过BeanDefinitionBuilder创建bean定义
		BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(HessianServiceExporter.class);
		beanDefinitionBuilder.addPropertyReference("service", hessianServiceImplRefBean);
		beanDefinitionBuilder.addPropertyValue("serviceInterface", hessianServiceInterface.getName());

		// 注册bean
		StringBuilder accessUrl = new StringBuilder("/");
		accessUrl.append(hessianServiceInterface.getSimpleName());
		accessUrl.append(suffix);

		LOGGER.info("Register hessian server url: {}", accessUrl.toString());
		beanFactory.registerBeanDefinition(accessUrl.toString(), beanDefinitionBuilder.getRawBeanDefinition());
	}

	/**
	 * 设置后缀
	 *
	 * @param suffix 后缀
	 */
	public void setSuffix(String suffix) {
		this.suffix = suffix;
	}
}